package subraSoft.centaurus.gui.option;

import java.awt.BorderLayout;
import java.util.List;
import java.util.Map;

import javax.swing.JPanel;
import javax.swing.event.ChangeListener;

import org.netbeans.validation.api.ui.ValidationGroup;
import org.netbeans.validation.api.ui.ValidationPanel;

import subraSoft.centaurus.gui.components.CenAlert;
import subraSoft.centaurus.gui.components.CenViewStack;
import subraSoft.centaurus.model.cobj.CenDefaultCObj;

/**
 * Componente que forma parte del optionController y concentra
 * la accion a realizar.
 * 
 * @author christian
 *
 */
public abstract class CenOption extends JPanel implements CenIErrorDisplayer
{
	private static final long serialVersionUID = 1L;
	
	private CenViewStack viewStack;
	private int selectedIndex = 0;
	
	/**
	 * Constructor.
	 */
	public CenOption()
	{
		setLayout(new BorderLayout());
		viewStack = new CenViewStack();
		add(viewStack, BorderLayout.CENTER);
	}
	
	/**
	 * Agrega un "Paso" a la opcion.
	 * 
	 * @param task paso a agregar.
	 */
	public void addTask(ValidationPanel task)
	{
		viewStack.add(task);
	}
	
	/**
	 * Obtiene el grupo al que deben agregarse los componentes
	 * que quieran validacion dinamica
	 * 
	 * @return el grupo de validacion
	 */
	public ValidationGroup getValidationGroup() 
	{
		return ((ValidationPanel)(viewStack.getSelectedComponent())).getValidationGroup();
	}
	
	/**
	 * Realiza la validacion previa a la finalizacion del
	 * proceso.
	 * 
	 * @return debe retornar null si no hay errores y sino un string 
	 * con el error a mostrar
	 */
	public abstract String validateOption();
	
	/**
	 * Avanza al siguiente paso de la opcion.
	 */
	public void moveForward()
	{
		String error = validateTask(selectedIndex);
		
		if(error != null)
		{
			CenAlert.showError(error);
			return;
		}
		
		selectedIndex++;
		viewStack.setSelectedIndex(selectedIndex);
	}
	
	/**
	 * Valida el paso del inidice pasado como parametro.
	 * 
	 * @param index indice a validar 
	 * @return null si no hay errores o un string con el error
	 */
	public abstract String validateTask(int index);

	/**
	 * Retrocede al paso anterior de la opcion.
	 */
	public void movePrevious()
	{
		selectedIndex--;
		viewStack.setSelectedIndex(selectedIndex);
	}
	
	/**
	 * Retorna true si hay otro paso pendiente.
	 * 
	 * @return true si hay otro paso pendiente.
	 */
	public boolean hasNext()
	{
		return selectedIndex < viewStack.getComponentCount()-1;
	}
	
	/**
	 * Retorna true si hay pasos anteriores.
	 * 
	 * @return true si hay pasos anteriores.
	 */
	public boolean hasPrevious()
	{
		return selectedIndex > 0;
	}
	
	/**
	 * Ejecuta la accion de la opcion. (SEGURO)
	 */
	/*protected void secureExecute() 
	{
		try {
			
		} 
		catch (Exception e) 
		{
			CenAlert.showError(e);
		}
	}*/
	
	/**
	 * Obtiene el nombre del archivo de reporte de jasper
	 * o null si no hay reporte.
	 * 
	 * @return el nombre del archivo de reporte o null si no 
	 * hay reporte.
	 */
	public String getReportFileName() {
		return null;
	}

	/**
	 * Obtiene los parametros para el reporte.
	 * 
	 * @return los parametros para el reporte.
	 */
	public Map<String, Object> getParameters() {
		return null;
	}

	/**
	 * Accion a ejecutar el finalizar la opcion.
	 */
	public abstract void execute();
	
	/**
	 * Realiza las tareas de inicializacion de la opcion, se ejecuta luego
	 * de crear los componentes visuales.
	 * 
	 * @param data info que llega del finder o chooser usado previamente
	 */
	public abstract void initOption(List<CenDefaultCObj> data);
	
	// -------------------------------------------------------
	
	// ERROR DISPLAYER
	
	@Override
	public void addChangeListener(ChangeListener cl) {
		ValidationPanel validationPanel = (ValidationPanel)viewStack.getSelectedComponent();
		validationPanel.addChangeListener(cl);
	}

	@Override
	public ValidationPanel getValidationPanel() {
		ValidationPanel validationPanel = (ValidationPanel)viewStack.getSelectedComponent();
		return validationPanel;
	}

	@Override
	public void removeChangeListener(ChangeListener cl) {
		ValidationPanel validationPanel = (ValidationPanel)viewStack.getSelectedComponent();
		validationPanel.removeChangeListener(cl);
	}

	/**
	 * Obtiene el titulo de la opcion.
	 * 
	 * @return el titulo de la opcion.
	 */
	public String getTitle() {
		return (selectedIndex+1) + "/"+viewStack.getComponentCount();
	}
}
